from django.conf import settings
from django.core.files.storage import Storage
from django.utils.deconstruct import deconstructible
from fdfs_client.client import Fdfs_client


@deconstructible
class FDFSStorage(Storage):
    def __init__(self, base_url=None, client_conf=None):
        """
        初始化
        :param base_url: 用于构造图片完整路径使用,图片服务器的域名
        :param client_conf: fdfs客户端配置文件的路径
        """
        if base_url is None:
            base_url = settings.FDFS_URL
        self.base_url = base_url

        if client_conf is None:
            client_conf = settings.FDFS_CLIENT_CONF
        self.client_conf = client_conf

    def _open(self, name, mode='rb'):
        """
        文件保存在fdfs中,读取由fdfs完成,不需要django完成open,故直接覆盖
        :param name:
        :param mode:
        :return:
        """
        pass

    def _save(self, name, content):
        """
        在fdfs中保存文件
        :param name: 传入的文件名
        :param content: 文件内容
        :return: 保存到数据库中fdfs的文件名
        """
        client = Fdfs_client(self.client_conf)
        ret = client.upload_by_buffer(content.read())
        if ret.get('Status') != 'Upload successed.':
            raise Exception("upload file failed")
        file_name = ret.get('Remote file_id')
        return file_name

    def url(self, name):
        """
        返回文件完整url路径
        :param name: 数据库中保存的文件名
        :return: 完整的url
        """
        return self.base_url + name

    def exists(self, name):
        """
        判断文件是否存在,fdfs可以自行解决文件的重名问题,因此此处返回false,告诉django上传的都是新文件
        :param name:
        :return:
        """
        return False